<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2023/8/18
 * Time: 11:15
 */

namespace app\logic\cron;


use app\common\lib\Common;
use app\common\lib\Constant;
use app\common\lib\RedisQueue;
use app\exception\IndexException;
use app\logic\BaseLogic;

use app\model\redis\RedisQueueModel;
use app\model\user\UserIncomeFlowModel;
use app\model\user\UserInviteRelationModel;
use app\model\user\UserModel;
use app\model\user\UserPointFlowModel;
use app\model\user\UserPromotionOrderIncomeModel;
use app\model\user\UserPromotionPlanModel;
use app\model\user\UserRechargeOrderIncomeModel;
use app\model\user\UserRechargeOrderModel;
use app\model\vip\ReceiveVipByMobileModel;
use support\Db;

class UserLogic extends BaseLogic
{
    protected static $instance;

    public function __construct()
    {
        parent::__construct();
    }

    public static function getInstance()
    {
//        if (is_object(self::$instance)) {
//            return self::$instance;
//        }

        return  new self();
    }

    public function userUpdateData()
    {
        $where = ['isdel'=>0, 'status'=>1];
        $where[] = [
            'or'=>[
                [['task_time','<',date('Y-m-d H:i:s',time()-(2*3600))]],
                [['task_time','null']]
          ]
        ];
        $data = UserModel::getInstance()->getWhere($where)->orderBy('task_time','asc')->limit(1000)->get();
        foreach ($data as $user){
            //1 用户邀请用户数更新
            $user->invit_user_nums = UserInviteRelationModel::getInstance()->getWhere(['user_sn'=>$user['user_sn'],'level'=>1])->count();
            $user->invit_one_user_nums = $user->invit_user_nums;

            //1-1 级别升级处理
            foreach([3,2,1] as $k){
                $levelData = config('param.vip_level'.$k);
                if($user->invit_user_nums>=$levelData['invite_number'] && $k>$user->agent_level){
                    $user->upgrade_agent_time = date('Y-m-d H:i:s');
                    $user->agent_level = $k;
                    break;
                }
            }

            //2 累计收益金额
            $user->total_income_amount = UserIncomeFlowModel::getInstance()->getWhere(['user_sn'=>$user['user_sn'],'type'=>1])->sum('amount');

            //3 充钱用户数
            $inviteUserSns = UserInviteRelationModel::getInstance()->getWhere(['user_sn'=>$user['user_sn'],'level'=>1])->pluck('invite_user_sn')->toArray();
            $chargeUserSns = UserPointFlowModel::getInstance()->getWhere([['user_sn','in',$inviteUserSns],'way'=>1,['type','in',[1,2]]])->groupBy('user_sn')->pluck('user_sn')->toArray();
            $user->charge_user_nums = count($chargeUserSns);
            $user->task_time = date('Y-m-d H:i:s');
            $user->save();

            // $isVip = $user['is_vip'];
            // //4 每天赠送点数
            // $user = $this->checkIsVip($user);
            // if($user['is_vip']==1){
            //     $where = [
            //         ['product_type', '=', 1],
            //         ['user_sn', '=', $user['user_sn']],
            //         ['order_status', '=', Constant::ORDER_STATUS_PAY_SUCCESS],
            //         ['pay_status', '=', Constant::ORDER_PAY_STATUS_SUCCESS],
            //         ['pay_time', '<>', ''],
            //         ['expires_date', '>=', strtotime(date('Y-m-d'))],
            //     ];
            //     $order = UserRechargeOrderModel::getInstance()->getWhere($where)->orderBy('point_nums','desc')->first();
            //     if($order){
            //         $where = [
            //             'user_sn'=>$user['user_sn'],
            //             'type'=>1,
            //             'way'=>1,
            //             ['created_at','>=',date('Y-m-d 00:00:00')]
            //         ];
            //         $pointNums = (int) UserPointFlowModel::getInstance()->getWhere($where)->sum('nums');
            //         if($pointNums<$order['point_nums']){
            //             $insert = [
            //                 'user_sn'=>$user['user_sn'],
            //                 'nums'=>round($order['point_nums']-$pointNums),
            //                 'type'=>1,
            //                 'way'=>1,
            //                 'sourceid'=>$order['id'],
            //                 'source_table'=>UserRechargeOrderModel::getInstance()->getTable(),
            //             ];
            //             UserPointFlowModel::getInstance()->insertGetId($insert);
            //         }
            //     }
            //     /* elseif($isVip==2){
            //         //领取一天vip还没到期，跨天
            //        $receive = ReceiveVipByMobileModel::getInstance()->getWhere(['mobile'=>$user['mobile']])->first();
            //        if($receive && (strtotime($receive['created_at'])+86400)>time()){
            //            $where = [
            //                'user_sn'=>$user['user_sn'],
            //                'type'=>1,
            //                'way'=>1,
            //                ['created_at','>=',date('Y-m-d 00:00:00')]
            //            ];
            //            $pointNums = (int) UserPointFlowModel::getInstance()->getWhere($where)->sum('nums');
            //            $givePointNums = config('param.test_vip_give_point',20);
            //            if($pointNums<$givePointNums){
            //                $insert = [
            //                    'user_sn'=>$user['user_sn'],
            //                    'nums'=>round($givePointNums-$pointNums),
            //                    'type'=>1,
            //                    'way'=>1,
            //                    'sourceid'=>$receive['id'],
            //                    'source_table'=>ReceiveVipByMobileModel::getInstance()->getTable(),
            //                ];
            //                UserPointFlowModel::getInstance()->insertGetId($insert);
            //            }
            //        }
            //     } */
            // }
        }

        return ['success'];
    }

    public function incomeSettlement()
    {
        //结算周期是7天
        $dateTimes = date('Y-m-d 00:00:00',strtotime('-7 day'));
        $where = [
            ['income_date','<',$dateTimes],
            ['settle_time','null'],
            'status'=>0,
            'type'=>1
        ];
        //不给特殊用户结算
        $notIncomeUsers = [];

        $data = UserIncomeFlowModel::getInstance()->getWhere($where)->orderBy('income_date','asc')->limit(200)->get();
        foreach($data as $val){
            //不给特殊用户结算
            if($notIncomeUsers && in_array($val['user_sn'],$notIncomeUsers)){
                continue;
            }
            try{
                Db::connection('mysql')->beginTransaction();
                $val->status = 1;
                $val->settle_time = date('Y-m-d H:i:s');
                $val->save();

                if($val['source_table']==UserPromotionOrderIncomeModel::getInstance()->getTable()){
                    UserPromotionOrderIncomeModel::getInstance()->getWhere(['id'=>$val['sourceid']])->update(
                        [
                            'status'=>1,
                            'settle_time'=>date('Y-m-d H:i:s')
                        ]
                    );
                }elseif($val['source_table']==UserRechargeOrderIncomeModel::getInstance()->getTable()){
                    UserRechargeOrderIncomeModel::getInstance()->getWhere(['id'=>$val['sourceid']])->update(
                        [
                            'status'=>1,
                            'settle_time'=>date('Y-m-d H:i:s')
                        ]
                    );
                }

                Db::connection('mysql')->commit();
            }catch (IndexException $e){
                Db::connection('mysql')->rollBack();
            }
        }

        return 'success';
    }

    public function promotionPlanMonitor()
    {
        $where = [
            'status'=>0,
            'isdel'=>0
        ];
        $userPlan = UserPromotionPlanModel::getInstance()->getWhere($where)->get();
        foreach($userPlan as $val){
            $queueData = RedisQueueModel::getInstance()->getWhere(['status'=>0,'name'=>'asyncGeneratedVideoData'])->pluck('data');
            $userPlanIds = [];
            foreach ($queueData as $v){
                $userPlanIds[] = json_decode($v,true)['user_planid'];
            }
            if(in_array($val['id'],$userPlanIds)){
                continue;
            }

            if((time()-strtotime($val['created_at']))>1800){
                //超过每半小时还没有加入队列表，可能是用户没走完流程就退出
                //生成唯一的请求id
                $requestId = Common::getRequestId();

                // 队列名
                $queue = 'asyncGeneratedVideoData';
                // 数据，可以直接传数组，无需序列化
                $data = ['requestid' => $requestId, 'user_planid' => $val['id']];
                // 投递消息
                RedisQueue::getInstance()->sendQueue($queue, $data);
            }
            usleep(50000);
        }

        return 'success';
    }

    // 每天赠送点数
    /*
    * 测试环境压测结果：每处理一万个用户用时3分钟
    */
    public function userPoint()
    {
        // 分布式锁，锁二十分钟
        if(Common::setnx('cronUserPoint', [], 1200)==false){
            return ['success'];
        }

        $where = ['isdel'=>0, 'status'=>1];
        // $where[] = [
        //     'or'=>[
        //         [['task_point_time','<',date('Y-m-d H:i:s',time()-(2*3600))]],
        //         [['task_point_time','null']]
        //     ]
        // ];
        $data = UserModel::getInstance()->getWhere($where)->orderBy('task_point_time','asc')->limit(50000)->get();

        foreach ($data as $user){
            $isVip = $user['is_vip'];
            // 每天赠送点数
            $user = $this->checkIsVip($user);
            if($user['is_vip']==1){
                $where = [
                    ['product_type', '=', 1],
                    ['user_sn', '=', $user['user_sn']],
                    ['order_status', '=', Constant::ORDER_STATUS_PAY_SUCCESS],
                    ['pay_status', '=', Constant::ORDER_PAY_STATUS_SUCCESS],
                    ['pay_time', '<>', ''],
                    ['expires_date', '>=', strtotime(date('Y-m-d'))],
                ];
                $order = UserRechargeOrderModel::getInstance()->getWhere($where)->orderBy('point_nums','desc')->first();
                if($order){
                    $where = [
                        'user_sn'=>$user['user_sn'],
                        'type'=>1,
                        'way'=>1,
                        ['created_at','>=',date('Y-m-d 00:00:00')]
                    ];
                    $pointNums = (int) UserPointFlowModel::getInstance()->getWhere($where)->sum('nums');
                    if($pointNums<$order['point_nums']){
                        $insert = [
                            'user_sn'=>$user['user_sn'],
                            'nums'=>round($order['point_nums']-$pointNums),
                            // 'nums'=>round(rand(1,900)),
                            'type'=>1,
                            'way'=>1,
                            'sourceid'=>$order['id'],
                            'source_table'=>UserRechargeOrderModel::getInstance()->getTable(),
                        ];
                        UserPointFlowModel::getInstance()->insertGetId($insert);
                    }
                }
            }

            $user->task_point_time = date('Y-m-d H:i:s');
            $user->save();
        }

        return ['success'];
    }

}